PPfuncties
----------
Deze functies zitten in de directory  /libraries/PPfuncties, die
een subdir is van de sketchboek-directory (bijv /Arduino/sources).
Hieronder staat per functie: 
1) een beschrijving ven de aanroepen van de functie.
2) een controlblock. Dat moet vooraan in de sketch worden geplaatst,
in ieder geval vr de eerste aanroep van een functie. Hierin staan
de mee te geven parameters beschreven evenals de door de functie
teruggegeven informatie.
3) achterin dit document zitten aansluitings gegevens en
pennummers voor zover dat nodig is.

***********************************************************************
PPSDkaart.h
    Lees- en schijftroutines voor SD-card.
    Er kunnen tot maximaal 4 files tegelijk geopend en bewerkt worden.
    Na openen worden de files gerefereerd met filenur 1 tm 4.
    Filenr 0 wordt intern door de routines gebruikt. 
-----------------------------------------------------------------------
    Functies
           NB: filenamen in dirs opgeven zonder voorloop /
               files in de root:   /filex
               files in subdir:    subdir/filey
      SDinitunit()            I
           Initialiseer SD-unit,
           moet eenmalig uitgevoerd worden.
           Deze functie wordt soms automatisch uitgevoerd
           om te testen of de unit nog ready is.
           SDunitstatus = 1 unit ready
           SDunitstatus = 9 unit niet ready of geen SDkaart
           NB: alle SDfilestatus[x] worden op 0 gezet
     SDopenDirectory(String dir) {
           Lees alle filenamen in de directory en sla op 
           in array SDfilenaam[]  
           SDdirstatus = 1  dir gelezen, entries in filenaam[]
                            direntries beginnen met /
           SDdirstatus = 2  dir gelezen, maar te veel files in
                            dir, rest genegeerd 
           SDdirstatus = 3  dir gelezen, maar out of memory error.
                            processing kan niet veiler verder gaan
                            dus stop en restart arduino 
           SDdirstatus = 9  SDunit niet ready
     SDprintdirentries(String dir)
           Print directory met subdirs (recursieve call)
     SDmakeDirectory(String dir) {
           Maak directory 
           SDdirstatus = 1  OK dir aangemaakt
           SDdirstatus = 9  error
     SDremoveDirectory(String dir) {
           Verwijder directory 
           SDdirstatus = 1  OK dir verwijderd
           SDdirstatus = 9  error
     SDcreatefile(String filenaam){
           Maak een lege file aan. 
           Als deze al bestand wordt deze eerst deleted
           Of de create gelukt is blijkt pas uit 
           achtereenvolgende reads of writes
     SDdeletefile(String filenaam){
           Delete file
     long SDfilesize(int filenr)
           Geeft de size van een geopende file
     SDseek(int filenr, positie)
           Zet de accesspointer voor volgende read of write
           NB: de eerste byte van de file is 0
     long  SDposition(int filenr)
           Geeft de accespointer voor de volgende read pf write,
           dat is het nummer van de volgende IO
           NB: de eerste byte van de file is 0
     bool  SDavailable(int filenr)
           Geeft availability van een geopende file
     SDopenfileread(int filenr, String filenaam)
           File wordt geopend voor read.
           SDfilestatus = 1  file klaar voor read
           SDfilestatus = 5  file open error
           SDfilestatus = 8  file open error
           SDfilestatus = 9  unit niet ready
     SDreadline(int filenr, String filenaam){
           Lees een lijn, alleen asci chars, CR is end of line 
           Input komt in String SDrecord
           SDfilestatus = 1 record data gelezen
           SDfilestatus = 5  end of file bereikt
     SDclosefile(int filenr){
           gewenst na lezen,
           nodig na schijven, anders wordt de filesize niet
           bijgewerkt en gaan de schfijfopdrachten verloren.
           SDfilestatus = 0     
     SDopenwrite(int filenr, String filenaam){
           Open file voor write.    
           Als de file niet bestaat wordt een lege aangemaakt
           SDfilestatus = 2  file klaar voor write
           SDfilestatus = 8  file open error 
           SDfilestatus = 9  unit niet ready
     SDopenappend(int filenr, String filenaam){
           Open file voor append. De hierna geschreven data
           wordt achteraan toegevoegd. 
           SDfilestatus = 2  file klaar voor append write
           SDfilestatus = 5  file open error
           SDfilestatus = 8  file open error
           SDfilestatus = 9  unit niet ready
     SDprintline(int filenr, String line){
           Schrijf een line, beeindigd met CRLF 
     SDreadByte(int filenr, byte databyte)
           Lees een byte. Geeft een nummer van 0 tm 255
     SDreadChar(int filenr, char datachar)
           Lees een chracter. Dit moet gedefinieerd zijn
           als char datachar en kan aan een String worden
           toegevoegd met stringa += datachar
     SDreadInt(int filenr, int dataint)
           Lees een integer
     SDreadIntDOS(int filenr, int dataint)
           Lees een integer Little endian (dos-format)
     SDreadLong(int filenr, long datalong){
           Lees een long integer
     SDreadLongDOS(int filenr, long datalong)
           Lees een long Little endian (dos-format)
     SDwriteByte(int filenr, byte databyte)
           Schrijf een byte, een nummer van 0 tm 255
     SDwriteChar(int filenr, byte databyte)
           Schrijf een chracter. Dit moet gedefinieerd zijn
           als char datachar.
     SDwriteInt(int filenr, int dataint){
           Schrijf een integer
     SDwriteIntDOS(int filenr, int dataint){\
           Schrijf een integer Little endian (dos-format)
     SDwriteLong(int filenr, long datalong)
           Schrijf een long 
     SDwriteLongDOS(int filenr, long datalong)
           Schrijf een long Little endian (dos-format)
-----------------------------------------------------------------------
Controlblock
-----------------------------------------------------------------------
int    SDunitstatus = 0; //1 = unit en kaart OK
                         //9 = niet ready
int    SDdirstatus = 0;  //1 = directory geopend,inhoud gelezen
                         //9 = dir niet geopend, 
                         //    unit niet ready,kaart niet OK
                         //    of dir bestaat niet
int    SDdirlevel = 0;   //root is level 0 etc
String SDfilenaam[100];  //ruimte voor 100 file- en dirnamen 
                         //dirs:   /xxxxxxx
                         //files:  xxxxxxx
long   SDfilecount = 0;  //aantal files in dir
long   SDdircount = 0;   //aantal dirs in dir
int    SDfilestatus[5];  //voor files 1 tm 4
                         // NB: file0 wordt door andere
                         //library-routines gebruikt,
                         //gebruik dus files 1 tm 4
                         //0 = file geclosed of deleted
                         //1 = file open voor read
                         //2 = file open voor write of append
                         //5 = end of file na read
                         //8 = file bestaat niiet
                         //9 = SDunit niet ready  
#include <PPSDkaart.h> 
***********************************************************************


***********************************************************************
PPSpiffs.h
    Lees- en schijftroutines voor SPIFFS.
    Er kan 1 file tegelijk geopend en bewerkt worden.
    SPIFFS kent geen subdirs.
----------------------------------------------------------------------
    Functies
           NB: filenamen opgeven zonder voorloop /
               files in de root:   /filex
               files in subdir:    subdir/filey
      SPinit()            
           Initialiseer SPIFFS voor IO
           moet eenmalig uitgevoerd worden.
           SPunitstatus = 1 SPIFFS ready
           SPunitstatus = 9 SPIFFS niet ready 
      SPopenDirectory(String dir) {
           Lees alle filenamen in de directory en sla op 
           in array SPfilenaam[]  
           SPdirstatus = 1  dir gelezen, entries in filenaam[]
                            direntries beginnen met /
           SPdirstatus = 2  dir gelezen, maar te veel files in
                            dir, rest genegeerd 
           SPdirstatus = 3  dir gelezen, maar out of memory error.
                            processing kan niet veiler verder gaan
                            dus stop en restart arduino 
           SPdirstatus = 9  SPunit niet ready
     SPprintdirentries(String dir)
           Print directory 
     SPcreatefile(String filenaam){
           Maak een lege file aan. 
           Als deze al bestand wordt deze eerst deleted
           Of de create gelukt is blijkt pas uit 
           achtereenvolgende reads of writes
     SPdeletefile(String filenaam){
           Delete file
     long SPfilesize(int filenr)
           Geeft de size van een geopende file
     SPseek(int filenr, positie)
           Zet de accesspointer voor volgende read of write
           NB: de eerste byte van de file is 0
     long  SPposition(int filenr)
           Geeft de accespointer voor de volgende read pf write,
           dat is het nummer van de volgende IO
           NB: de eerste byte van de file is 0
     bool  SPavailable(int filenr)
           Geeft availability van een geopende file
     SPopenfileread(int filenr, String filenaam)
           File wordt geopend voor read.
           SPfilestatus = 1  file klaar voor read
           SPfilestatus = 8  filenaam niet ingevuld
     SPreadline(int filenr, String filenaam){
           Lees een lijn, alleen asci chars, CR is end of line 
           Input komt in String SPrecord
           SPfilestatus = 1 record data gelezen
           SPfilestatus = 5  end of file bereikt
     SPclosefile(int filenr){
           gewenst na lezen,
           nodig na schijven, anders wordt de filesize niet
           bijgewerkt en gaan de schfijfopdrachten verloren.
           SPfilestatus = 0     
     SPopenwrite(int filenr, String filenaam){
           Open file voor write.    
           Als de file niet bestaat wordt een lege aangemaakt
           SPfilestatus = 2  file klaar voor write
           SPfilestatus = 8  filenaam niet ingevuld 
     SPopenappend(int filenr, String filenaam){
           Open file voor append. De hierna geschreven data
           wordt achteraan toegevoegd. 
           SPfilestatus = 2  file klaar voor append write
           SPfilestatus = 5  file open error
           SPfilestatus = 8  filenaam nie ingevuld
     SPprintline(int filenr, String line){
           Schrijf een line, beeindigd met CRLF 
     SPreadByte(int filenr, byte databyte)
           Lees een byte. Geeft een nummer van 0 tm 255
     SPreadChar(int filenr, char datachar)
           Lees een chracter. Dit moet gedefinieerd zijn
           als char datachar en kan aan een String worden
           toegevoegd met stringa += datachar
     SPreadInt(int filenr, int dataint)
           Lees een integer
     SPreadIntDOS(int filenr, int dataint)
           Lees een integer Little endian (dos-format)
     SPreadLong(int filenr, long datalong){
           Lees een long integer
     SPreadLongDOS(int filenr, long datalong)
           Lees een long Little endian (dos-format)
     SPwriteByte(int filenr, byte databyte)
           Schrijf een byte, een nummer van 0 tm 255
     SPwriteChar(int filenr, byte databyte)
           Schrijf een chracter. Dit moet gedefinieerd zijn
           als char datachar.
     SPwriteInt(int filenr, int dataint){
           Schrijf een integer
     SPwriteIntDOS(int filenr, int dataint){\
           Schrijf een integer Little endian (dos-format)
     SPwriteLong(int filenr, long datalong)
           Schrijf een long 
     SPwriteLongDOS(int filenr, long datalong)
           Schrijf een long Little endian (dos-format)

-----------------------------------------------------------------------
Controlblock
-----------------------------------------------------------------------
//---------------------------------------------------
int    SPunitstatus = 0; //1 = SPIFF beschikbaar
int    SPdirstatus = 0;  //1 = directory geopend, inhoud gelezen
                         //2 = dir geopend, maar teveel files in
                         //    dir, rest genegeerd
                         //9 = dir niet geopend, 
                         //    unit niet ready,kaart niet OK
                         //    of dir bestaat niet
int    SPdirlevel = 0;   //root is altijd level 0
String SPfilenaam[101];  //ruimte voor 1000 file- en dirnamen 
                         //NB: 1 meer opgeven dan SPIFFfilemax
int    SPfilemax = 100;  //maximum aantal files per directory
long   SPfilecount = 0;  //aantal files in dir
int    SPfilestatus = 0;  
                         //0 = file geclosed of deleted
                         //1 = file open voor read
                         //2 = file open voor write of append
                         //5 = end of file na read
                         //8 = file open error
                         //9 = SPunit niet ready  
long SPfileinx = 0;

#include <PPspiffs.h> 
//--------------------------------------------------

***********************************************************************



***********************************************************************
PPsortstring.h 
     Alfabetisch sorteren stringarray
-----------------------------------------------------------------------
     Sortstring(String arraynaam, int lowInx, int highInx, int Opties) 
         lowInx,  nr van eerste element in de array (eerste = 1)
         highInx, nr van laatst element in de array
         Opties: 0 - asc, non case sensitive
                 1 - asc, case sensitive (A komt voor a)
                 2 - desc, non case sensitive
                 3 - desc, case sensitive (A komt voor a)
-----------------------------------------------------------------------
Controlblock
-----------------------------------------------------------------------
#include <PPSortstring.h> 
***********************************************************************


***********************************************************************
PPLCDscherm.h
     LCD scherm 16x2  of 20x4 met I2C-module
-----------------------------------------------------------------------
  Functies:
    LCDinit()  eenmalige initialisatie 
    LCDclear()
    LCDbacklight()
    LCDnobacklight()
    LCDdisplayregel(String tekst,int line, int col)
         line is 0 tm 3
         de eerste positie op de regel is 0
    LCDscrollendisplayregel(String tekst,int col)
         lines 2 tm 4 worden omhoog geschoven
         de tekst wordt op regel 4 gezet
    LCDscrollendisplayregel(String tekst,int col){
         line 1 wordt omhoog geschoven
         de tekst wordt op regel 1 gezet

   NB: de I2C-module heeft een vast adres 0x27, houd hiermee 
       rekening als er meerdere I2C modules zijn.
  
------------------------------------------------------------------------
Controlblock
------------------------------------------------------------------------
#define LCD4regels      // als deze regel actief is, 20x4 scherm
int     LCDstatus = 0;  //1 = LCD ready
                        //2 = niet ready
#include <PPLCDscherm.h>
***********************************************************************


***********************************************************************
PPTimers.h  
  Timer routines
  
------------------------------------------------------------------------
  Functies:
    TIMERinit()
       wordt eenmalig tijdens setup gedaan  
    TIMERdelay(long microsecs){  
       wacht aantal microseconden. Dit gebruik je bij niet-tijdkritische
       processen. Let op: timerdelay blokkert de hele processor, ook
       eventuele IO-interrupts worden uitgesteld.
       Voor tijdkritische processen kan beter de combinatie
       timerstart/timerwait worden gebruikt. Deze hinderen niet (zoals
       timerdelay wel doet) de interne IO-interrupts.
    TIMERstart(long microsecs){   
    TIMERwait()        
       wacht tot timer afgelopen is.
       Na aflopen wordt de timer gereset.
       Het aantal gemiste interrups komt in TIMERexceed,
       zie TIMERhasinterrupted.
    TIMERreset()
       reset timer zodat TIMERwait direct doorloopt en een daarna eventueel
       uitgevoerde TIMERhasinterrupted true geeft.
    TIMERhasinterrupted()
       Bool, uitvragen met "if(TIMERhasinterrupted)"
       Is true - als de timer was afgelopen, 
               - als timer niet gestart was
               - als timer gereset was
       Is false als de timer nog loopt.
       In alle gevallen loopt de processing na timerhasinterrupted
       direct door. Het is dus alleen een test van de status van de timer.
       Het aantal gemiste interrups komt in TIMERexceed,
       dit is hoger dan 0 als er de ondertussen uitgevoerde instructies
       langer hebben geduurd dan de timer-interval. Hiermee kan indien
       nodig gecontroleerd worden of de Arduino snel genoeg is om processing
       binnen bepaalde andere acties kan worden uitgevoerd (timing controle).

    NB: 
       voor tijdkritische processen is het processing schema het beste
       als volgt:
       TIMERinit (eenmalig)
       while(){
        TIMERstart
        Hierna de benodigde processing tijdens de timervalue.
        Deze valt dan geheel binnen de ingestelde wait time,
        tenzij de processor daarvoor te traag is. Dit kan worden
        uitgetest met uittesten van de waarde timerexceeded. 
        TIMERwait
       )
   ------------------------------------------------------------------------
Controlblock
-------------------------------------------------------------------------
long TIMERexceed = 0;   //aantal gemiste timerinterrupts
#include <PPTimers.h>
***********************************************************************


***********************************************************************
PPprintfilehex.h
   File op SD hex uitprinten
------------------------------------------------------------------------
   Functie:
     Printfilehex(filenaam)
-----------------------------------------------------------------------
Controlblock
-----------------------------------------------------------------------
#include <PPprintfilehex.h>  
***********************************************************************


***********************************************************************
PPMCP23017.h
    Aansturen 16-port output expansion unit MCP23017 of PCF8575
    op basis van I2C. De twee soorten kunnen door elkaar op n
    I2C-bus worden aangesloten. De verschillen in processing
    worden in deze module opgelost en zijn dus transparant voor de
    gebruiker. 
------------------------------------------------------------------------
  Functies:
    MCPinit(byte adres, byte Afunctie, byte Bfunctie)  
        Initialiseren van alle pinnen van de MCP23017 
        NB hoeft maar eenmalig, of als pinnen een andere functie krijgen.
        Adres opgeven en pinnen instellen voor input of output
        Het adres van de MCP is hex 20tm27, afhankelijk van adresjumpers
        jumper A0 telt voor 1, A1 voor 2 en A2 voor 4.
        Afunctie en Bfunctie zijn de functiebits voor de poorten A en B,
        die ieder acht bits hebben voor acht pinnen.
        Als een pin output moet zijn staat de bit uit
        Als een pin input moet zijn staat de bit aan
        Bijv:   MCPinit( 0x20, B00000001, B11111110) 
                     poort A pin 7 tm 1 output, pin0 input
                     poort B pin 7 tm 1 input,  pin0 output
       Dit kan je ook opgeven als:
               MCPinit( 32, 1, 254) of (0x20 , 0x01, 0xFE)
       MCPstatus = 1  Unit ready
       MCPstatus = 9  Unit ready of afwezig (let op adres)
   MCPsetPin(byte  adres, byte pinnummer ){
        Aanzetten van een pin van de MCP23017
        Pinnummers van groep A en B zijn doorgenummerd als 0 tm 15
   MCPresetPin(byte  adres, byte  pinnummer ){
        Uitzetten van een pin van de MCP23017
        Pinnummers van groep A en B zijn doorgenummerd als 0 tm 15
   MCPflipPin(byte adres, byte pinnummer){
        Wisselen van een pin van de MCP23017
        Pinnummers van groep A en B zijn doorgenummerd als 0 tm 15
   MCPsetAllpins(byte adres, byte byteA, byte byteB){
        Aanzetten/uitzetten van alle pinnen van de MCP23017
        byteA en byteB bevatten de som van de pinwaarden van de pinnen
   MCPreadPin(byte adres, byte pinnummer){
        Bool om een pin van de MCP23017 uit te lezen
        Aanroep bijv: "if MCPreadPin(0x20, 5) == TRUE)
        NB, ook de status van outputpinnen kan worden uitgelezen
        Pinnummers van groep A en B zijn doorgenummerd als 0 tm 15
   MCPreadAllpins(byte adres, byte byteA, byte byteB){
        Uitlezen van alle pinnen van de MCP23017
        NB, ook de status van outputpinnen kan worden uitgelezen
        byteA en byteB bevatten de som van de pinwaarden van de pinnen
------------------------------------------------------------------------
Controlblock
-----------------------------------------------------------------------
int MCPstatus = 0 ;
#include <PPMCP23017.h>
***********************************************************************

***********************************************************************
PPEEprom.h
   Lezen en schrijven van een byte, int of long naar/van EEprom
   NB: in de arduino staan integers en long integers genoteerd in
       Big endian. Dat wil zeggen dat de high order byte (MSB)
       rechts staat en dus als laatste byte geschreven wordt.
   LET OP: de writes worden gebufferd en pas weggeschreven na een 
           EEpromcommit.
------------------------------------------------------------------------
 Functies:
    void 
    int  EEpromlength(){
         Arduino only: geeft de lengte van de EEprom op het board 
         NB: bij ESP32 moet je het aantal te gebruiken bytes aangeven 
         met EEprombegin
    EEprombegin(aantbytes)
         maakt EEprom toegankelijk voor aantbytes (ESP32)
         NB: Arduino stelt automatisch alle bytes ter beschikking,
             EEprombegin is hier niet nodig, maar mag wel. 
    EEpromreadByte(int adres, byte databyte)
         leest byte van adres op Eprom
    EEpromreadInt(int adres, int dataint)
         leest integer van adres op EEprom
    EEpromreadLong(int adres, long datalong)
         leest long van adres op EEprom 
    EEpromwriteByte(int adres, byte databyte)
         schrijft byte naar adres op EEprom
    EEpromwriteInt(int adres, int dataint)
         schrijft integer naar adres op EEprom
    EEpromwriteLong(int adres, long datalong)
         schrijft long naar adres op EEprom 
    EEpromcommit()
         activeert de schrijfacties, nodig bij ESP's, mag bij AVR   
------------------------------------------------------------------------
Controlblock
-----------------------------------------------------------------------
#include <PPEEprom.h>
***********************************************************************



***********************************************************************
PPmidiwritefileSD.h
   Schrijven van een midifile op SD
------------------------------------------------------------------------
 Functies:
   MidiwriteheaderSD(String filenm, long trackleng){
      Maakt een vaste header met tempo MM100
   MidiwriteEventSD(byte mes,byte data1, byte data2, 
                    long deltatime, long trackleng){
      Schrijf midi-event
      Deltatime in millisecs opgeven
   MidiwriteEOFSD(long trackleng){
      Schrijft EOF-event en vult tracklengte in de header in
------------------------------------------------------------------------
Controlbock
------------------------------------------------------------------------
#include <PPmidiwritefile.h>
***********************************************************************


***********************************************************************
PPmidiwritefileSP.h
   Schrijven van een midifile op SPIFFS
------------------------------------------------------------------------
 Functies:
   MidiwriteheaderSP(String filenm, long trackleng){
      Maakt een vaste header met tempo MM100
   MidiwriteEventSP(byte mes,byte data1, byte data2, 
                    long deltatime, long trackleng){
      Schrijf midi-event
      Deltatime in millisecs opgeven
   MidiwriteEOFSD(long trackleng){
      Schrijft EOF-event en vult tracklengte in de header in
------------------------------------------------------------------------
Controlbock
------------------------------------------------------------------------
#include <PPmidiwritefileSP.h>
***********************************************************************



***********************************************************************
PPmidireadfileSD.h    Lezen van een midifile op SD
  en
PPmidireadfileSP.h    Lezen van een midifile op SPIFFS

In een sketch mag een van beide tegelijk aanwezig zijn, dus
let daarop bij de include.
Ze gebruiken hetzelfde controlblock en dezelfde functies.
Dus bij de keuze voor SD of SPIFFS hoeft alleen de juiste include 
gebruikt te worden.

Midifiles mogen zowel format 0 als format 1 zijn.
------------------------------------------------------------------------
 Functies:
   MidiOpenfileread(String filenaam)
     Open midifile voor achtereenvolgende reads)
   MidiReadfilenote(long &deltams, String &soort, 
                 int &nootnr, byte &track, byte &channel, byte &velocity){
     Lees alle midinote-events een voor een in

------------------------------------------------------------------------
Controlbock
------------------------------------------------------------------------
long  Midifilesize = 0;       //lengte op disk
int   Midistatus = 0;         //0 file not open
                              //1 = midifile OK
                              //2 = geen MTrk (format eror)
                              //3 = geen fmt0 of 1
                              //5 = EOF
                              //7 = structuur-error
                              //8 = file open error
int   Midiformat = 0;         //0 (alleen trk 0), 1(trk0 en trk1,2 etc)
int   Miditicksperkwart = 48; //default
float Miditempo = 500000;     //mm120 bij 120 ticksperkwart
int   Midiaanttracks = 0;     //1 bij fmt0, aant bij fmt1 (incl trk0)
float Midimspertick = 10.4;   //=tempo/1000/ticksperkwart
byte  Midilastevent = 0;      //tbv running status
long  Miditrackleng[32] ;     //exclusief MTrk en llll
long  Miditrackadres[32];     //begin position in file
long  Midiposition[32];       //current position in file
long  Midieventnr[32];        //eventnr binnen track           
#include <PPmidireadfile.h>
***********************************************************************




Aansluitingsgegevens diverse apparaten
----------------------------------------- 

SD-kaart via digitale pinnen

        - +5v  naar +5v
        - de GND naast MISO naar GND
                 Mega   ESP32  ardPro  ESP12
        - CS(SS)  53     5      43      D0(16) D8(15) boot niet
                                               met SDcard in slot
        - MOSI    51    23     icsp     D7(13)
        - SCK     52    18     icsp     D5(14)
        - MISO    50    19     icsp     D6(15)
        - 3,3v en de GND daarnaast niet aansluiten

SdFat  

LCD met I2C
      VCC naar 5v (3,3v werkt niet)
      GND naar GND
      SDA naar 20 op Mega, 21 op ESP32, D2(5) op ESP12
      SCL naar 21 op Mega, 22 op ESP32, D1(4) op ESP12

Buttons
      button naar PIN
      button naar GND
      100k tussen PIN en GND anders is de pin instabiel
 
Lichtsensor
      S naar PIN
      + naar 5v
      - naar GND
        geen weerstand nodig
LED
     plus (lange pootje, kleine segment) van LED 
                       via 500R/1.8K weerstand naar PIN
     min  (korte pootje, grote segment) van LED naar GND 
 
RELAIS
     5v relay naar 5v
     GND naar GND
     IN1 naar PIN
     jumper op  JD-VVV naar VCC
     NB: pin HIGH is relais is uit
     Om te voorkomen dat een relais aanslaat bij start van het programma
     de volgende manier van initialiseen gebruiken:       
         digitalWrite (RELpin, HIGH) ;  zet eerst relaiscontact uit 
      dan daana pas:
     pinMode (RELpin, OUTPUT ) ;    als output toekennen

Steppermotor met step/dir driver
     step en dir pinnen als output instellen
     NB: de ENApin hoeft niet aangesloten te worden
             Als deze toch is aangesloten en HIGH is 
             staat de motor spanningsloos in vrijloop.
 
MCP23017 - 16-port IO-expansion unit, op basis van I2C
      VCC naar 5v (3,3v werkt niet)
      GND naar GND
      SDA naar 20 op Mega, 21 op ESP32
      SCL naar 21 op Mega, 22 op ESP32
      - zet jumpers A0, A1 en A2 voor een adres tussen 0x20 en 0x27
        Hou rekening met eventuele andere I2C-apparaten
      - INTA en INTB zijn interruptpinnen, zie MCP-doc
      - de pinnen werken zoals de Arduino pinnen

PCF8575 - 16-port IO-expansion unit, op basis van I2C
      VCC naar 5v 
      GND naar GND
      SDA naar 20 op Mega, 21 op ESP32
      SCL naar 21 op Mega, 22 op ESP32
      - zet jumpers A0, A1 en A2 voor een adres tussen 0x20 en 0x27
        Midden-Gnd hoeft niet te worden gesoldeerd
        Hou rekening met eventuele andere I2C-apparaten
      - soldeer VCC aan VDD. Daardoor hoef je de VDD(2x) en de
        Gnd(2x) aan beide zijden niet aan te sluiten.  
      - INT is een  interruptpin, zie PCF-doc
      - de pinnen werken niet zoals de Arduino pinnen,
        het outputvermogen is te klein om bijv ULN2803's
        aan te sluiten. Verbind de outputs van de PCF daarvoor 
        ook via een weerstand van 18k tot 27k met de plus. 
        Bij een ULN2803 neem je daarvoor de plus aan de outputs 
        van de ULN. Anders kan je de 5v van de PCF zelf gebruiken.


DINsocket voor midi output
      Gezien vanaf de soldeerzijde:   1      3
                                        4  5
                                          2                           
      TX (of TX1) via 220 Ohm naar pen 5 van de DINsocket
      5v via 220 Ohm naar pin 4 van de DINsocket
      Pin2 naar Gnd Aan de plugkant gaat deze naar de 
           massaomschermingsdraad van de kabel

